package com.shuijing.boot.transaction.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuijing.boot.transaction.entity.User;
import com.shuijing.boot.transaction.mapper.UserMapper;
import com.shuijing.boot.transaction.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 刘水镜
 * @blog https://liushuijinger.blog.csdn.net
 * @since 2021-04-22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper mapper;

    /**
     * 使用REQUIRED传播级别添加用户
     * 如果当前存在事务，支持当前事务；如果没有事务，开启新的事务
     * 此方法主要用于演示在有事务存在时的行为
     *
     * @param user 要添加的用户对象
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void addWithRequired(User user) {
        mapper.insert(user);
    }

    /**
     * 使用REQUIRED传播级别添加用户，并故意抛出异常
     * 如果当前存在事务，支持当前事务；如果没有事务，开启新的事务
     * 此方法主要用于演示在有事务存在时，抛出异常如何触发事务回滚
     *
     * @param user 要添加的用户对象
     * @throws RuntimeException 总是抛出的异常，用于触发事务回滚
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void addWithRequiredAndException(User user) {
        mapper.insert(user);
        throw new RuntimeException("Required 触发事务回滚，抛出外部异常");
    }

    /**
     * 使用REQUIRES_NEW传播级别添加用户
     * 无论如何总是开启新的事务
     * 此方法主要用于演示在任何情况下都会开启新事务的行为
     *
     * @param user 要添加的用户对象
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addWithRequiredNew(User user) {
        mapper.insert(user);
    }

    /**
     * 使用REQUIRES_NEW传播级别添加用户，并故意抛出异常
     * 无论如何总是开启新的事务
     * 此方法主要用于演示在新事务中，抛出异常如何触发事务回滚
     *
     * @param user 要添加的用户对象
     * @throws RuntimeException 总是抛出的异常，用于触发事务回滚
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addWithRequiredNewAndException(User user) {
        mapper.insert(user);
        throw new RuntimeException("Required_New 触发事务回滚，抛出外部异常");
    }

    /**
     * 使用NESTED传播级别添加用户
     * 如果当前存在事务，开启嵌套事务；如果没有事务，行为类似于REQUIRED
     * 此方法主要用于演示嵌套事务的使用
     *
     * @param user 要添加的用户对象
     */
    @Override
    @Transactional(propagation = Propagation.NESTED)
    public void addWithNested(User user) {
        mapper.insert(user);
    }

    /**
     * 使用NESTED传播级别添加用户，并故意抛出异常
     * 如果当前存在事务，开启嵌套事务；如果没有事务，行为类似于REQUIRED
     * 此方法主要用于演示在嵌套事务中，抛出异常如何触发事务回滚
     *
     * @param user 要添加的用户对象
     * @throws RuntimeException 总是抛出的异常，用于触发事务回滚
     */
    @Override
    @Transactional(propagation = Propagation.NESTED)
    public void addWithNestedAndException(User user) {
        mapper.insert(user);
        throw new RuntimeException("Nested 触发事务回滚，抛出外部异常");
    }

}
